

/*





*/

//#include "ledc.h"

#define UPDATE  35
#define LEDSHOW 1
#define BLINK 2
#define PAOMA 3
#define BREATHE 4
#define CHANGE_COLOR 5
#define ALL_ON       6
#define ALL_OFF      7


#include <HTTPUpdate.h>

/*------------------------定义设备相关数据-----------------------------*/
String TID = "1";//测试号
String DEV = "1";//负责局部控制的设备，通过 tid=1 and topic=1 查询 设备库中该设备下包含的关键参数
//https每次都要阻塞个五秒，对wifi安全性要求高，需要使用安全的wifi库，这里寻卡的时候使用http而不是s，低频，低量
String baseUrl = "http://xf.mianmianshi.com";
/*------------------------定义wifi相关数据-----------------------------*/
#include <WiFiMulti.h>






//1当前固定场所

const char* wifi_name_b = "卢本伟广场";
const char* wifi_psd_b = "12345678";



//2通用热点
const char* wifi_name_a = "yqwl";
const char* wifi_psd_a = "88888888";



#include <HTTPClient.h>
#include <ArduinoJson.h>//字符串处理
WiFiMulti wifiMulti;     //全局使用

/*------------------------定义mqtt相关数据-----------------------------*/
WiFiClient wfclient;
#include <PubSubClient.h>
PubSubClient client(wfclient);
const char*mqttServer = "47.100.188.31";
const int mqttPort = 1883;
const char*mqttUser = "root";
const char*mqttPassword = "root";
String mqttTopic;
String mqttClientId ;





// define two tasks
void TaskLed( void *pvParameters );
void TaskCard( void *pvParameters );

// the setup function runs once when you press reset or power the board
void setup() {


  Serial.begin(115200);










  /*--------------------wifi---------------------------------*/
  wifiMulti.addAP(wifi_name_a, wifi_psd_a);
  wifiMulti.addAP(wifi_name_b, wifi_psd_b);
  //  wifiMulti.addAP(wifi_name_a, wifi_psd_a);


  //如果联网了就可以继续运行
  while (wifiMulti.run() != WL_CONNECTED) {
    vTaskDelay(500);
    Serial.print(".");
  }


  if (wifiMulti.run() == WL_CONNECTED) {
    Serial.println("");
    Serial.println("WiFi connected");
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }



  /*--------------------mqtt订阅---------------------------------*/

  // clientId += String(random(0xffff), HEX)


  mqttClientId = TID + "_" + DEV;
  mqttTopic = TID + "_" + DEV;

  Serial.println("Connectedto the WiFi network");
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);
  while (!client.connected()) {
    Serial.println("Connectingto MQTT...");
    const char* clientId = mqttClientId.c_str();

    if (client.connect(clientId)) {
      Serial.println("connected");
    } else {
      Serial.print("failedwith state ");
      Serial.print(client.state());
      vTaskDelay(1000);
    }
  }
  //根据既定规则生成topic
  const char* topic = mqttTopic.c_str();
  client.subscribe(topic, 1);




  /***********************************************************************/
  // Now set up two tasks to run independently.
  xTaskCreatePinnedToCore(
    TaskLed
    ,  "TaskLed"   // A name just for humans
    ,  1024 * 16 // 看情况给
    ,  NULL
    ,  1  // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,  NULL
    ,  tskNO_AFFINITY); //tskNO_AFFINITY :表示双核运行 0:cpu0,1:cpu1

  xTaskCreatePinnedToCore(
    TaskCard
    ,  "TaskCard"
    ,  1024 * 8 // Stack size
    ,  NULL
    ,  1  // Priority
    ,  NULL
    ,  1);

  // Now the task scheduler, which takes over control of scheduling individual tasks, is automatically started.
  /***********************************************************************/

}

void loop()
{

  //   if(wifiMulti.run() != WL_CONNECTED) {
  //        Serial.println("WiFi not connected!");
  //        vTaskDelay(1000);
  //    }


  // Empty. Things are done in Tasks.
}

/*--------------------------------------------------*/
/*---------------------- Tasks ---------------------*/
/*--------------------------------------------------*/

void TaskLed(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

  /*
    led灯控制程序
  */
  for (;;) // A Task shall never return or exit.
  {
    if (!client.connected()) {//如果没连上
      reconnect();//重连
    }
    client.loop();
  }//for end


}


void TaskCard(void *pvParameters)  // This is a task.
{
  (void) pvParameters;

  /*
    其他程序
  */

  for (;;)
  {
    vTaskDelay(10000);
    //空闲

  }
}



/***********************************************************************/



void my_update1(char* url) {

  WiFiClient client;
  Serial.println("开始升级.......");

  t_httpUpdate_return ret = httpUpdate.update(client, url);


  switch (ret) {
    case HTTP_UPDATE_FAILED:
      Serial.printf("HTTP_UPDATE_FAILED Error (%d): %s\n", httpUpdate.getLastError(), httpUpdate.getLastErrorString().c_str());

      break;

    case HTTP_UPDATE_NO_UPDATES:
      Serial.println("HTTP_UPDATE_NO_UPDATES");


      break;
    case HTTP_UPDATE_OK:
      Serial.println("HTTP_UPDATE_OK");
      break;
  }
}





/*
  mqtt消息接收回调方法
*/
void callback(char*topic, byte* payload, unsigned int length) {
  Serial.print("Messagearrived in topic: ");
  Serial.println(topic);
  Serial.print(" length: ");
  Serial.println(length);

  uint8_t code = payload[length - 1]; //指令下标
  uint16_t dataLength = length - 1;//数据长度



  switch (code) {


    case UPDATE:

      //c++可以这样写
      //      String update_url =  "";
      //      for (int i = 1; i < dataLength; i++) {
      //        update_url += (char)payload[i];
      //      }

      //c写法 //把字节数组转成字符串
      char* url = (char*)payload;
      url[dataLength] = '\0';
      Serial.println(url);
      my_update1(url);
      break;
  }

}


void reconnect() {

  // Loop until we're reconnected
  while (!client.connected() && (wifiMulti.run() == WL_CONNECTED)) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    const char* clientId = mqttClientId.c_str();
    if (client.connect(clientId)) {
      Serial.println("connected --clientId");
      Serial.println(clientId);

      // Once connected, publish an announcement...
      client.publish("outTopic", "hello world");
      // ... and resubscribe
      const char* topic = mqttTopic.c_str();
      client.subscribe(topic, 1);
      Serial.println("topic------");
      Serial.println(topic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 3 seconds");
      // Wait 5 seconds before retrying
      vTaskDelay(3000);
    }
  }
}
